<template>
  <div class="main">
    <div class="tool-box">
      <div class="logo-box">
        <h3>TPSHION</h3>
      </div>
      <div class="btn-box">
        <div class="opt-box">
          <el-button type="info" @click="openOSS">已上传文件</el-button>
          <el-button type="success" @click="toSecret">密钥管理</el-button>
          <el-button type="warning" @click="toSSHManage">SSH管理</el-button>
          <el-button type="primary" @click="addFlow">创建流水线</el-button>
        </div>
      </div>
    </div>
    <div class="flow-box">
      <div v-if="list.length > 0" class="card-wrap">
        <el-card class="box-card" @click="openHistoryFlow(item)" shadow="hover" body-style="padding: 0 10px;" v-for="(item, index) in list" :key="index">
          <div class="title-box">
            <h4 style="overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">{{ item.name }}</h4>
          </div>
          <el-divider style="margin-top: 1px; margin-bottom: 5px; border-color: #409EFF;"/>
          <div class="branch-box">
            <el-link style="color: #409EFF;" :icon="Share">{{ getRunBranch(item.nodeDataList) }}</el-link>
          </div>
          <div class="btn-box">
            <el-tooltip content="删除流水线" placement="bottom">
              <el-button size="small" type="danger" :icon="Delete" circle @click="deleteFlowItem(item)"/>
            </el-tooltip>
            <el-tooltip content="构建历史" placement="bottom">
              <el-button size="small" type="info" :icon="Histogram" circle @click="openHistoryFlow(item)"/>
            </el-tooltip>
            <el-tooltip content="编辑流水线" placement="bottom">
              <el-button size="small" type="primary" :icon="Edit" circle @click="openEditFlow(item.taskId)"/>
            </el-tooltip>
            <el-tooltip content="立即构建" placement="bottom">
              <el-button size="small" type="success" :icon="VideoPlay" circle @click="runFlow(item.taskId)"/>
            </el-tooltip>
          </div>
        </el-card>
      </div>
      <el-empty v-else description="没有项目" />
    </div>

    <el-drawer v-model="drawer" :direction="direction" size="850" :title="drawerTitle" :before-close="handleClose">
      <el-table :data="hisList" height="calc(100vh - 120px)" v-loading="loading">
        <el-table-column width="90" label="构建序号" fixed>
          <template #default="scope">
            <el-tooltip effect="light" content="查看日志" placement="top-start">
              <span style="color: #409EFF; cursor: pointer;" @click="openHistoryLog(scope.row)">#{{ scope.row.batchId }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column width="70" label="状态">
          <template #default="scope">
            <el-tag v-if="scope.row.status === 'success'" type="success">成功</el-tag>
            <el-tag v-if="scope.row.status === 'error'" type="danger">失败</el-tag>
            <el-tag v-if="scope.row.status === 'stop'" type="warning">中断</el-tag>
          </template>
        </el-table-column>
        <el-table-column width="100" label="分支">
          <template #default="scope">
            <el-link style="color: #409EFF;" :icon="Share">{{ scope.row.branch }}</el-link>
          </template>
        </el-table-column>
        <el-table-column width="80" property="totalTime" label="耗时" />
        <el-table-column width="100" label="git版本">
          <template #default="scope">
            <span>{{ scope.row.commitVersion ? scope.row.commitVersion.substring(0,8) : '' }}</span>
          </template>
        </el-table-column>
        <el-table-column width="108" property="startTime" label="开始时间" />
        <el-table-column width="108" property="endTime" label="结束时间" />
        <el-table-column property="commitMsg" label="提交信息" />
      </el-table>
    </el-drawer>

    <el-dialog
      v-model="logShow"
      :title="logTitle"
      fullscreen
      :before-close="handleLogClose"
    >
      <div v-loading="logLoading" class="his-log">
        <p v-for="(item,index) in logList" :key="index">{{ item }}</p>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleLogClose">关闭</el-button>
        </span>
      </template>
    </el-dialog>

    <el-drawer v-model="drawerOSS" :direction="direction" size="750" :title="ossTitle" :before-close="handleOSSClose">
      <el-table :data="ossList" height="calc(100vh - 120px)" v-loading="ossLoading">
        <el-table-column width="380" label="文件名称">
          <template #default="scope">
            <span style="color: #409EFF;">{{ scope.row.key }}</span>
          </template>
        </el-table-column>
        <el-table-column width="110" prop="size" label="大小"/>
        <el-table-column width="108" prop="time" label="时间"/>
        <el-table-column fixed="right" label="操作" width="100">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="handleDownloadClick(scope.row)">下载</el-button>
            <el-button link type="danger" size="small" @click="handleDeleteClick(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { getFlowList, deleteFlow } from '../api/TaskApi'
import { TaskWork, FlowHistory } from "../model/TaskModel"
import { ElLoading, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import { Edit, Share, Delete, VideoPlay, Histogram } from '@element-plus/icons-vue'
import { GitData, NodeData } from '../model/NodeModel'
import { historyList, historyLog } from '../api/FlowApi'
import { FileInfo } from '../model/FileInfoModel'
import { fileList, downloadFile, deleteFile } from '../api/OSSApi'

const router = useRouter()
const list = ref<TaskWork[]>([])
const hisList = ref<FlowHistory[]>([])
const drawer = ref(false)
const direction = ref('rtl')
const drawerTitle = ref<string>()
const loading = ref<boolean>(false)
const logList = ref<string[]>([])
const logShow = ref<boolean>(false)
const logLoading = ref<boolean>(false)
const logTitle = ref<string>('构建日志')
const drawerOSS = ref<boolean>(false)
const ossTitle = ref<string>('oss文件列表')
const ossList = ref<FileInfo[]>([])
const ossLoading = ref<boolean>(false)

onMounted(() => {
  init()
})

const init = async () => {
  await initWorkList()
}

/**
 * 初始化列表
 */
const initWorkList = async () => {
  const loading = getLoading('数据加载中...')
  const rs = await getFlowList()
  loading.close()

  if(rs.data){
    list.value = rs.data
  }else{
    list.value = []
  }
}

const getLoading = (msg:string):any  =>{
  return ElLoading.service({
    lock: true,
    text: msg,
    background: 'rgba(0, 0, 0, 0.7)',
  })
}

/**
 * 创建流水线
 */
const addFlow = () => {
  router.push({
    path: 'editFlow'
  })
}

const toSecret = () => {
  router.push({
    path: 'secret'
  })
}

/**
 * 删除流水线
 */
const deleteFlowItem = (taskWork:TaskWork) => {
  ElMessageBox.confirm('删除 ' + taskWork.name + '?',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    await deleteFlow(taskWork.taskId)
    await initWorkList()
  }).catch(() => {})
}

/**
 * 编辑流水线
 */
const openEditFlow = (taskId:string) => {
  router.push({
    path: 'editFlow',
    query: {taskId: taskId}
  })
}

/**
 * 运行流水线
 */
const runFlow = (taskId:string) => {
  router.push({
    path: 'runFlow',
    query: {taskId: taskId}
  })
}

/**
 * 获取运行分支
 */
const getRunBranch = (nodeDataList: NodeData[] | undefined):string => {
  if(!nodeDataList || nodeDataList.length <= 0){
    return 'master'
  }

  const gitDataList = nodeDataList.filter(i => i.type == 'git')
  if(!gitDataList || gitDataList.length <= 0){
    return 'master'
  }

  const data = gitDataList[0].data as GitData
  return data.branch ? data.branch : data.defaultBranch
}

const openHistoryFlow = async (taskWork:TaskWork) => {
  drawerTitle.value = taskWork.name
  loading.value = true
  const rs = await historyList(taskWork.taskId)
  if(rs.data){
    hisList.value = rs.data
  }else{
    hisList.value = []
  }
  loading.value = false
  drawer.value = true
}

const handleClose = () => {
  drawer.value = false
  hisList.value = []
}

const openHistoryLog = async (flowHistory:FlowHistory) => {
  logShow.value = true
  logLoading.value = true
  logTitle.value = drawerTitle.value + " (#" + flowHistory.batchId + ")"
  const rs = await historyLog(flowHistory.taskId, flowHistory.batchId)
  if(rs.data){
    logList.value = rs.data
  }else{
    logList.value = []
  }
  logLoading.value = false
}

const handleLogClose = () => {
  logShow.value = false
  logList.value = []
}

const toSSHManage = () => {
  router.push({
    path: 'sshManage'
  })
}

const handleOSSClose = () => {
  drawerOSS.value = false
  ossList.value = []
}

const openOSS = async () => {
  drawerOSS.value = true
  ossLoading.value = true
  const rs = await fileList()
  ossLoading.value = false
  if(rs.data){
    ossList.value = rs.data
  }
}

const handleDownloadClick = async (row:FileInfo) => {
  ossLoading.value = true
  const rs = await downloadFile(row)
  ossLoading.value = false
  if(rs.data){
    const link = document.createElement('a');
    link.href = rs.data;
    link.setAttribute('download', row.key.replace('app/', ''));
    link.click();
  }
}

const handleDeleteClick = async (row:FileInfo) => {
  ElMessageBox.confirm('删除文件 ' + row.key + '?',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(async () => {
    await deleteFile(row)
    const rs = await fileList()
    if(rs.data){
      ossList.value = rs.data
    }
  }).catch(() => {})
}

</script>

<style lang="less" scoped>
.main{
  width: 100vw;
  height: 100vh;

  .tool-box{
    height: 60px;
    background-color: #7a7fd3;
    display: flex;
    align-items: center;
    justify-content: end;

    .logo-box{
      width: 100px;
      height: 60px;
      color: #ffffff;
      position: absolute;
      left: 15px;
    }

    .btn-box{
      height: 60px;
      padding-left: 10px;
      padding-right: 10px;
      display: flex;
      align-items: center;

      .title-box{
        width: 250px;
        height: 60px;
        color: #ffffff;
        display: flex;
        align-items: center;
      }

      .opt-box{
        height: 60px;
        display: flex;
        align-items: center;
      }
    }
  }

  .flow-box{
    height: calc(100vh - 60px);

    .card-wrap{
      display: flex;
      flex-wrap: wrap;
      padding: 10px;

      .box-card{
        min-width: 200px;
        max-width: 300px;
        height: 98px;
        border-color: #409EFF;
        margin: 30px;

        .title-box{
          height: 30px;
          display: flex;
          align-items: center;
          justify-content: center;
        }

        .branch-box{
          height: 20px;
          display: flex;
          justify-content: start;
          align-items: center;
          padding-bottom: 8px;
        }

        .btn-box{
          display: flex;
          justify-content: end;
        }
      }
    }
  }

  .his-log{
    height: calc(100vh - 200px); 
    background-color: #000000; 
    color: #FFFFFF; 
    padding: 10px; 
    border-radius: 5px;
    overflow: scroll;
  }
}
</style>